﻿using System.Text;
using MoXAML.Infrastructure;
using EnvDTE;

namespace MoXAML.PowerToys.Classic
{
    /// <summary>
    /// The comment command is used to comment out blocks of XAML. This goes above and beyond the Visual Studio
    /// XAML commenting, which has problems when you try to comment out previously commented out code.
    /// </summary>
    /// <remarks><para>Revision history:</para>
    /// <para>Based on chaiguy's feedback, commenting now supports adding in empty comment blocks 
    /// (suitable for adding new comments).</para>
    /// <para>The commenting now copes with VS inserted comments, by converting them to /* and */ items
    /// when a new comment is performed on it.</para>
    /// </remarks>
    public class UncommentCommand : CommentBase
    {
        public UncommentCommand()
            : base()
        {
            this.CommandName = "CommandUncommentXaml";
            this.Caption = "Uncomment XAML";
        }

        /// <summary>
        /// This command is only supported if text has been selected.
        /// </summary>
        /// <returns>The command status.</returns>
        public override vsCommandStatus GetStatus()
        {
            if (!Application.IsTextSelected())
                return vsCommandStatus.vsCommandStatusSupported;
            return base.GetStatus();
        }

        public override void Execute()
        {
            TextSelection selection = Application.TextSelection();
            if (selection == null) return;
            
            string openComment = OpenComment;
            // First of all, find the opening comment...
            string text = selection.Text;
            // Now, remove this...
            string output = ExtractString(openComment, text, string.Empty);
            string closeComment = CloseComment;
            output = output.Replace(closeComment, string.Empty);
            string nextComment = OpenInnerComment;
            output = ExtractString(nextComment, output, openComment);
            int position = output.LastIndexOf(CloseInnerComment);
            string finalOutput = output;
            if (position > 0)
            {
                finalOutput = string.Format("{0}{1}{2}", output.Substring(0, position), CloseComment, output.Substring(position + 2));
            }
            /*
            string openComment = "<!--";
            // First of all, find the opening comment...
            string text = selection.Text;
            // Now, remove this...
            string output = ExtractString(openComment, text, string.Empty);
            string closeComment = "-->";
            output = output.Replace(closeComment, string.Empty);
            string nextComment = "/*";
            output = ExtractString(nextComment, output, openComment);
            int position = output.LastIndexOf("* /");
            string finalOutput = output;
            if (position > 0)
            {
                finalOutput = output.Substring(0, position) + "-->" + output.Substring(position + 2);
            }*/

            EditPoint point = selection.TopPoint.CreateEditPoint();
            selection.ReplaceText(selection.Text, finalOutput, (int)vsFindOptions.vsFindOptionsMatchCase);
        }

        private static string ExtractString(string comment, string text, string replacementText)
        {
            int position = text.IndexOf(comment);
            string output = text;
            if (position >= 0)
            {
                output = string.Format("{0}{1}{2}", text.Substring(0, position), replacementText, text.Substring(position + comment.Length));
            }
            return output;
        }
    }
}